using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NGourd.Core.Reports
{
    public abstract class NUnitNodeFormatter
    {
        protected ReportNode node;

        public NUnitNodeFormatter(ReportNode node)
        {
            this.node = node;
        }

        public abstract string OpenTag();
        public abstract string CloseTag();
		
		public string EscapeText(string text)
		{
            text = text.Replace("&", "&amp;");
            text = text.Replace("<", "&lt;");
            text = text.Replace(">", "&gt;");
			return text.Replace("\"", "&quot;");
		}
    }

    public class FeatureNUnitNodeFormatter : NUnitNodeFormatter
    {
        public FeatureNUnitNodeFormatter(ReportNode node)
            : base(node)
        {
        }

        public override string OpenTag()
        {
            var template = @"<test-suite name=""{0}"" success=""{1}"" time=""1"" asserts=""{2}""><results>";
            return String.Format(template,
                EscapeText(node.Text),
                node.Status == ReportStatus.PASSED,
                node.Flatten().Where(n => n.TargetType == ReportTarget.STEP).Count()
            );
        }

        public override string CloseTag()
        {
            return "</results></test-suite>";
        }

    }

    public class ScenarioNUnitNodeFormatter : NUnitNodeFormatter
    {
        public ScenarioNUnitNodeFormatter(ReportNode node)
            : base(node)
        { }

        public override string OpenTag()
        {
            var template = @"<test-suite name=""{0}"" success=""{1}"" time=""1"" asserts=""{2}""><results>";
            return String.Format(template,
                EscapeText(node.Text),
                node.Status == ReportStatus.PASSED,
                node.Nodes.Count
            );
        }

        public override string CloseTag()
        {
            return "</results></test-suite>";
        }
    }

    public class StepNUnitNodeFormatter : NUnitNodeFormatter
    {
        public StepNUnitNodeFormatter(ReportNode node)
            : base(node)
        {
        }

        public override string OpenTag()
        {
            var template = @"<test-case name=""{0}"" executed=""{1}"" success=""{2}"" time=""1"" asserts=""1""/>";
            return String.Format(template,
                EscapeText(node.Text),
                node.Status == ReportStatus.SKIPPED ? "False" : "True",
                node.Status == ReportStatus.PASSED ? "True" : "False");
        }

        public override string CloseTag()
        {
            return String.Empty;
        }
    }

}
